#!/usr/bin/python
# -*- coding: utf-8 -*-

class ObjReader(object):
    """Stellt Methoden zum einlesen (parsen) von Punkt und obj Dateien bereit"""
    def __init__(self, filename):
        self.filename = filename
        self.vertices = []
        self.textures = []
        self.vertex_normals = []
        self.faces = []

        self._raw_points = [] # Punkte aus .raw Datei

        
    def _get_face(self, line):
        polygon = []
        for point in line:
            vertice = []
            point = point.split("/")
            if len(point)==1:
                vertice.append(self.vertices[int(point[0])-1])
                vertice.append([])
                vertice.append([])
            elif len(point)==3:
                if point[1]=="":
                    vertice.append(self.vertices[int(point[0])-1])
                    vertice.append([])
                    vertice.append(self.vertex_normals[int(point[2])-1])
                else:
                    vertice.append(self.vertices[int(point[0])-1])
                    vertice.append(self.textures[int(point[1])-1])
                    vertice.append(self.vertex_normals[int(point[2])-1])
            else:
                raise Exception("Fehlerhafte Datei!")
            polygon.append(vertice)
        return polygon


        
    def read_file(self):
        f = open(self.filename, 'r')

        for line in f.readlines():
            line = line.split()
            if len(line) == 0:
                print "Leerzeile"
            elif len(line) != 4:
                raise Exception("Fehlerhafte .obj-Datei, bekomme diese Zeile: %s\nDateiname: %s" % (line, self.filename) )
            elif line[0] == "v":
                self.vertices.append([float(line[1]), float(line[2]), float(line[3])])
            elif line[0] == "vt":
                self.textures.append([float(line[1]), float(line[2]), float(line[3])])
            elif line[0] == "vn":
                self.vertex_normals.append([float(line[1]), float(line[2]), float(line[3])])
            elif line[0] == "f":
                self.faces.append(self._get_face(line[1:]))
            else:
                raise Exception("Fehlerhafte Datei!")

    def __repr__(self):
        output = ""
        if len(self.faces)==0:
            output = "Datei wurde noch nicht gelesen mit read_file() oder ist fehlerhaft!"
        else:
            output = "Anzahl der Vertices(Eckpunkte): %s\n" % len(self.vertices)
            output += "Anzahl der Texturen: %s\n" % len(self.textures)
            output += "Anzahl der Vertex-Normalen: %s\n" % len(self.vertex_normals)
            output += "Anzahl der Faces(Polygone): %s" % len(self.faces)
        return output

    def read_raw_file(self):
        """Liest eigene .raw datei ein"""
        print 'in read_raw_file'
        self._raw_points = self.get_raw_data()
        
    def get_raw_data(self, filename=None):
        """Erwartet Punktedatei .raw mit 3 Koordinaten je Zeile und gibt sie
        als Liste von Punkten zurueck"""
        if filename is None:
            filename=self.filename
            if filename[-4:]=='.obj':
                raise AttributeError ('*.raw Datei erwartet, bekam: %s.' % filename)
        raw_points = [map(float,line.split())
                      for line in file(filename)]
        self._raw_points = raw_points
        return raw_points

    def get_vertex_list(self # ObjReader objekt
                        ):
        """Gibt liste der Punkte zurueck wie sie zum initialisieren eines VBO benoetigt werden"""
        vertex_list = []
        
        # TODO: assert parser gibt nur gueltige obj datei zurueck
        vertices = self.vertices
        vertex_normals = self.vertex_normals
        textures = self.textures
        
        # [ [vetexliste], [normalenliste], [texturliste]   
        lis = [lis for lis in (vertices, vertex_normals, textures) if lis != []]
        structure = []
        # TODO: andere facestets testen, evtl diese methode in den parser setzen 
        if vertex_normals and textures:
            vertex_list = zip(lis[0], lis[1], lis[2])
        elif vertex_normals:
            vertex_list = zip(lis[0], lis[1])
        else:
            vertex_list = lis[0]
            print vertex_list[0]
            return vertex_list
    

    # Properties (getter setter)
    def _get_raw_points(self):
        return self._raw_points
    def _set_raw_points(self, filename):
        """Dateiname wird automatisch eingelesen und in liste gewandelt"""
        self._raw_points = self.get_raw_data(filename)
    raw_points = property(_get_raw_points, _set_raw_points, None, None)

if __name__ == "__main__":
    pass
    ## dat = ""
    ## reader = ObjReader(dat)
    ## reader.raw_points = dat
    ## print reader._raw_points[:1]
    

    

    

                                
